using System;
using System.Collections.Generic;
using Chronicle.Parser;

namespace Chronicle.Analyzation
{
	public class AnalyzeVisitor : IEventVisitor
	{
		bool logEvents;
		bool curEventUnnamed = true;
		internal EventInformation curEvent;
		internal EventInformation allEvents = new EventInformation () { EventName = "All Fights"} ;
		
		internal List<EventInformation> eventList = new List<EventInformation> ();
		
		#region IEventVisitor implementation
		
		public event EventHandler<EventInformationEventArgs> EventCreated;
		protected virtual void OnEventCreated (EventInformationEventArgs e)
		{
			EventHandler<EventInformationEventArgs> handler = this.EventCreated;
			if (handler != null)
				handler (this, e);
		}
		
		public void Visit (EventCombatBegin combatBegin)
		{
			logEvents = true;
			curEvent = new EventInformation();
			curEvent.EventName = "<New Event>";
			curEvent.StartTime = combatBegin.TimeStamp;
			curEventUnnamed = true;
			eventList.Add(curEvent);
			OnEventCreated (new EventInformationEventArgs (curEvent));
		}
		
		public void Visit (EventCombatEnd combatEnd)
		{
			if (curEvent != null) {
				curEvent.EndTime = combatEnd.TimeStamp;
				curEvent.TotalSeconds = (combatEnd.TimeStamp - curEvent.StartTime).TotalSeconds;
				allEvents.TotalSeconds += curEvent.TotalSeconds;
			}
			logEvents = false;
		}

		public void Visit (EventBuff eventBuff)
		{
		}

		public void Visit (EventRecourceGain eventBuffGot)
		{
		}

		public void Visit (EventBuffGot eventBuffGot)
		{
		}

		public void Visit (EventDebuffGot eventDebuffGot)
		{
		}

		public void Visit (EventDebuffLost eventDebuffLost)
		{
		}

		public void Visit (EventBuffLost eventBuffLost)
		{
		}

		public void Visit (EventCastDisrupted eventCastDisrupted)
		{
		}

		public void Visit (EventImmune eventImmune)
		{
		}

		public void Visit (EventFavorGain eventFavorGain)
		{
		}

		public void Visit (EventRedirect eventRedirect)
		{
		}
		
		public event EventHandler<EventEventArgs> EventAvoidAttack;
		protected virtual void OnEventAvoidAttack (EventEventArgs e)
		{
			var handler = this.EventAvoidAttack;
			if (handler != null)
				handler (this, e);
		}
		
		public void Visit (EventAvoidAttack eventAvoidAttack)
		{
			if (!logEvents)
				return;
			OnEventAvoidAttack (new EventEventArgs (eventAvoidAttack));
		}
		
		public event EventHandler<EventEventArgs> EventParryAttack;
		protected virtual void OnEventParryAttack (EventEventArgs e)
		{
			var handler = this.EventParryAttack;
			if (handler != null)
				handler (this, e);
		}
		public void Visit (EventParryAttack eventParryAttack)
		{
			if (!logEvents)
				return;
			OnEventParryAttack (new EventEventArgs (eventParryAttack));
		}
		
		public event EventHandler<EventEventArgs> EventMissedAttack;
		protected virtual void OnEventMissedAttack (EventEventArgs e)
		{
			var handler = this.EventMissedAttack;
			if (handler != null)
				handler (this, e);
		}
		public void Visit (EventMissedAttack eventMissedAttack)
		{
			if (!logEvents)
				return;
			OnEventMissedAttack (new EventEventArgs (eventMissedAttack));
		}
		
		public event EventHandler<EventEventArgs> EventResistAttack;
		protected virtual void OnEventResistAttack (EventEventArgs e)
		{
			var handler = this.EventResistAttack;
			if (handler != null)
				handler (this, e);
		}
		public void Visit (EventResistAttack eventResistAttack)
		{
			if (!logEvents)
				return;
			OnEventResistAttack (new EventEventArgs (eventResistAttack));
		}

		public event EventHandler<EventEventArgs> EventTargetKilled;
		protected virtual void OnEventTargetKilled (EventEventArgs e)
		{
			var handler = this.EventTargetKilled;
			if (handler != null)
				handler (this, e);
		}

		public void Visit (EventTargetKilled eventTargetKilled)
		{
			if (!logEvents)
				return;
			OnEventTargetKilled (new EventEventArgs (eventTargetKilled));
		}

		public event EventHandler<EventEventArgs> EventDie;
		protected virtual void OnEventDie (EventEventArgs e)
		{
			var handler = this.EventDie;
			if (handler != null)
				handler (this, e);
		}

		public void Visit (EventDie eventDie)
		{
			if (!logEvents)
				return;
			OnEventDie (new EventEventArgs (eventDie));
		}

		public event EventHandler<EventEventArgs> EventHeal;
		protected virtual void OnEventHeal (EventEventArgs e)
		{
			var handler = this.EventHeal;
			if (handler != null)
				handler (this, e);
		}

		public void Visit (EventHeal eventHeal)
		{
			if (!logEvents)
				return;
			OnEventHeal (new EventEventArgs (eventHeal));
		}

		public event EventHandler<EventEventArgs> EventDamage;
		protected virtual void OnEventDamage (EventEventArgs e)
		{
			var handler = this.EventDamage;
			if (handler != null)
				handler (this, e);
		}

		public void Visit (EventDamage eventDamage)
		{
			if (!logEvents)
				return;
			if (curEventUnnamed && eventDamage.ActorType == ActorType.Player && eventDamage.TargetType == ActorType.Npc) {
				curEvent.EventName = eventDamage.TargetName;
				curEventUnnamed = false;
			}
			OnEventDamage(new EventEventArgs (eventDamage));
		}
		#endregion
		
		public void Reset()
		{
			logEvents = false;
			curEvent = null;
			allEvents = new EventInformation () { EventName = "All Fights"} ;
			eventList.Clear ();
		}
	}
}
